package com.haisen.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.haisen.core.utils.PageResultSet;
import com.haisen.core.utils.ResultCodeEnum;
import com.haisen.dataobject.dto.UserDto;
import com.haisen.dataobject.entity.Group;
import com.haisen.dataobject.entity.Organization;
import com.haisen.dataobject.entity.Role;
import com.haisen.dataobject.entity.User;
import com.haisen.dataobject.mapper.base.UserMapper;
import com.haisen.dataobject.query.UserQuery;
import com.haisen.exception.BizException;
import com.haisen.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import javax.persistence.Transient;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private GroupService groupService;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private PasswordHelper passwordHelper;

    @Override
    public PageResultSet<UserDto> findByPage(UserQuery userQuery) {

        if(!StringUtils.isEmpty(userQuery.getOrderBy())) {
            PageHelper.orderBy(userQuery.getOrderBy());
        }

        Weekend<User> example = Weekend.of(User.class);
        WeekendCriteria<User, Object> criteria = example.weekendCriteria();

        if (!StringUtils.isEmpty(userQuery.getUsername())) {
            criteria.andLike(User::getUsername, "%" + userQuery.getUsername() + "%");
        }
        if(userQuery.getLocked() != null) {
            criteria.andEqualTo(User::getLocked,userQuery.getLocked());
        }

        List<UserDto> dtoList = new ArrayList<>();

        PageHelper.offsetPage(userQuery.getOffset(), userQuery.getLimit());
        userMapper.selectByExample(example).forEach(u -> {
            UserDto dto = new UserDto(u);
            dto.setOrganizationName(getOrganizationName(Long.valueOf(dto.getOrganizationId())));
            dto.setRoleNames(getRoleNames(dto.getRoleIdList()));
            dto.setGroupNames(getGroupNames(dto.getGroupIdList()));
            dtoList.add(dto);
        });

        long total = userMapper.selectCountByExample(example);
        PageResultSet<UserDto> resultSet = new PageResultSet<>();
        resultSet.setRows(dtoList);
        resultSet.setTotal(total);
       // log.info("dotlist zise={},total={}",dtoList.size(),total);
        return resultSet;
    }

    private String getGroupNames(Collection<Long> groupIds) {
        if (CollectionUtils.isEmpty(groupIds)) {
            return "";
        }

        StringBuilder s = new StringBuilder();
        for (Long groupId : groupIds) {
            Group role = groupService.findOne(groupId);
            if (role != null) {
                s.append(role.getName());
                s.append(",");
            }
        }

        if (s.length() > 0) {
            s.deleteCharAt(s.length() - 1);
        }

        return s.toString();
    }


    private String getRoleNames(Collection<Long> groupIds) {
        if (CollectionUtils.isEmpty(groupIds)) {
            return "";
        }

        StringBuilder s = new StringBuilder();
        for (Long roleId : groupIds) {
            Role role = roleService.findOne(roleId);
            if (role != null) {
                s.append(role.getDescription());
                s.append(",");
            }
        }

        if (s.length() > 0) {
            s.deleteCharAt(s.length() - 1);
        }

        return s.toString();
    }

    private String getOrganizationName(Long organizationId) {
        Organization organization = organizationService.findOne(organizationId);
        if (organization == null) {
            return "";
        }
        return organization.getName();
    }

    @Override
    @Transactional
    public void createUser(User user) {
        User u = findByUsername(user.getUsername());
        if (u != null) {
            throw new BizException(ResultCodeEnum.FAILED_USER_ALREADY_EXIST);
        }
        // 加密密码
        passwordHelper.encryptPassword(user);
        userMapper.insertSelective(user);
    }

    @Override
    @Transactional
    public void updateUser(User user) {
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    @Transactional
    public void deleteUser(Long userId) {
        userMapper.deleteByPrimaryKey(userId);
    }

    @Override
    @Transient
    public void saveUser(User user) {
        User u = findByUsername(user.getUsername());
        if (u != null){
            user.setId(u.getId());
            //每次登录密码不能更新
            user.setPassword(u.getPassword());
            //店长一线员工已经分配了默认角色，不再修改,由手工处理
            //原来的角色不修改，如果设置为null，不行
            user.setRoleIds(u.getRoleIds());
            updateUser(user);
        }else {
            createUser(user);
        }
    }

    @Override
    @Transactional
    public void changePassword(Long userId, String newPassword) {
        User user = userMapper.selectByPrimaryKey(userId);
        user.setPassword(newPassword);
        passwordHelper.encryptPassword(user);
        userMapper.updateByPrimaryKey(user);
    }

    @Override
    public User findOne(Long userId) {
        return userMapper.selectByPrimaryKey(userId);
    }

    @Override
    public List<User> findAll() {
        return userMapper.selectAll();
    }

    @Override
    public User findByUsername(String username) {
        User user = new User();
        user.setUsername(username);
       // userMapper.selectOne(user);
//        log.info("登录用户，获取用户名：{}", JSON.toJSONString(userMapper.select(user)));
        return userMapper.selectOne(user);
    }

    @Override
    public User findByDingUserId(String dingUserId) {
        User user = new User();
        user.setDingUserId(dingUserId);
        return userMapper.selectOne(user);
    }

    @Override
    public List<User> queryLikeName(String name) {
        Weekend<User> example = Weekend.of(User.class);
        WeekendCriteria<User,Object> criteria = example.weekendCriteria();
        criteria.andLike(User :: getUsername,'%'+name+'%');
      List<User> userList=  userMapper.selectByExample(example).stream()
                .map( o ->{
            o.setUsername("");
            o.setPassword("");
            o.setSalt("");
            o.setGroupIds("");
            o.setRoleIds("");
            return o;
        }).collect(Collectors.toList());
        return userList;
    }

    @Override
    public Set<String> findNickNameByname(String name){
        Weekend<User> example = Weekend.of(User.class);
        WeekendCriteria<User,Object> criteria = example.weekendCriteria();
        criteria.andLike(User :: getNickName,'%'+name+'%');
        return  userMapper.selectByExample(example).stream()
                .map( o ->{
                    return o.getNickName();
                }).collect(Collectors.toSet());
    }


    @Override
    public Set<String> findRoles(String username) {
        User user = findByUsername(username);
        if (user == null) {
            return Collections.EMPTY_SET;
        }
        return roleService.findRoles(user.getRoleIdList().toArray(new Long[0]));
    }

    //根据用户名获取权限列表
    @Override
    public Set<String> findPermissions(String username) {
        User user = findByUsername(username);
        if (user == null) {
            return Collections.EMPTY_SET;
        }
        return roleService.findPermissions(user.getRoleIdList().toArray(new Long[0]));
    }
}
